package com.mgs.tagger.controller
{
	import com.mgs.tagger.appdata.dto.FileItemDTO;
	import com.mgs.tagger.appdata.dto.TagDTO;
	import com.mgs.tagger.appdata.dto.WorkspaceDTO;
	import com.mgs.tagger.log.Level;
	import com.mgs.tagger.log.Logger;
	import com.mgs.tagger.model.FileItemUI;
	import com.mgs.tagger.model.Model;
	import com.mgs.tagger.model.TagUI;
	
	import flash.events.EventDispatcher;
	import flash.events.IEventDispatcher;
	
	import mx.collections.ArrayList;
	
	public class TagController extends EventDispatcher
	{
		private static var _instance:TagController;
		
		public static function get instance():TagController{
			if(_instance == null){
				_instance = new TagController();
			}
			return _instance;
		}
		function TagController()
		{
		}
		public function filter(tag:TagDTO, state:Boolean):void{
			tag.selected = state;
			updateItems();
		}
		internal function updateItems():void{
			var al:ArrayList = new ArrayList();
			for each(var o:Object in Model.instance.allFileItems.source){
				if(matchFilter(o as FileItemUI)){
					al.addItem(o);
				}
			}
			Logger.instance.log(Level.INFO, al.length + " elements found matching filter");
			Model.instance.displayedFileItems = al;
		}
		private function matchFilter(item:FileItemUI):Boolean{
			// match si match le classification.
			return matchFilterRecursiveSelected(item, Model.instance.workspace.classification);
		}
		private function matchFilterRecursiveSelected(item:FileItemUI, tag:TagDTO):Boolean{
			var childTag:TagDTO;
			if(tag.selected){
				// match si l'item contient le tag
				if(item.dto.tags.indexOf(tag) >= 0){
					return true;
				}
				// ou si l'item contient un tag enfant (même non seléctionné).
				for each(childTag in tag.children){
					if(matchFilterRecursiveUnselected(item, childTag)){
						return true;
					}
				}
				// sinon ne match pas.
				return false;
			}else{
				// match si tous les enfant match
				for each(childTag in tag.children){
					if(!matchFilterRecursiveSelected(item, childTag)){
						return false;
					}
				}
				// sinon match
				return true;
			}
		}
		private function matchFilterRecursiveUnselected(item:FileItemUI, tag:TagDTO):Boolean{
			if(item.dto.tags.indexOf(tag) >= 0){
				return true;
			}
			for each(var childTag:TagDTO in tag.children){
				if(matchFilterRecursiveUnselected(item, childTag)){
					return true;
				}
			}
			return false;
		}
		
		public function createTag(tag:String):void{
			var t:TagDTO = new TagDTO();
			t.name = tag;
			t.color = 0xFF7F00; // TODO random color
			t.files = new Vector.<FileItemDTO>();
			Model.instance.allTags.addItem(t);
			Model.instance.workspace.classification.children.push(t);
		}
		internal function load(workspace:WorkspaceDTO):void{
			Model.instance.allTags = new ArrayList();
			for each(var t:Object in workspace.classification.children){
				Model.instance.allTags.addItem(t);
			}
			Model.instance.classification = new TagUI(workspace.classification);
		}
		public function tag(file:FileItemUI, tag:TagDTO):void{
			if(file.dto.tags.indexOf(tag) < 0){
				file.dto.tags.push(tag);
				file.tags.addItem(tag);
				tag.files.push(file.dto);
			}
		}
		public function untag(file:FileItemUI, tag:TagDTO):void{
			if(file.dto.tags.indexOf(tag) >= 0){
				file.dto.tags.splice(file.dto.tags.indexOf(tag), 1);
				file.tags.removeItem(tag);
				tag.files.splice(tag.files.indexOf(file.dto), 1);
			}
		}
	}
}